package me.timlong.controller;

import com.alibaba.druid.util.StringUtils;
import me.timlong.controller.viewObject.UserVO;
import me.timlong.error.BusinessException;
import me.timlong.error.EmBusinessError;
import me.timlong.response.CommonReturnType;
import me.timlong.service.UserService;
import me.timlong.service.model.UserModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller("user")
@RequestMapping("/user")
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
//  **  DEFAULT_ALLOWD_HEADERS 允许跨域传输所有的参数，将用于token放入header域，做session共享的跨域请求   ** // 划重点： 解决跨域请求问题
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private RedisTemplate redisTemplate;

    // 用户登录接口
    @RequestMapping(value = "/login", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType login(@RequestParam(name = "telephone") String telephone,
                                  @RequestParam(name = "password") String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        if (StringUtils.isEmpty(telephone) || StringUtils.isEmpty(password)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        // 用户登录服务，校验y用户登录是否合法
        UserModel userModel = this.userService.validateLogin(telephone, this.encodeByMd5(password));

        // 将用户的登录凭证加入到成功登录的session内
        //  若用户登录成功验证后，需要将对应的登录信息和登录凭证存入到redis中去

        String uuidToken = UUID.randomUUID().toString();
        uuidToken = uuidToken.replace("-", "");
        // 将生成的唯一的 UUID与userModel相关联存入到redis中
        redisTemplate.opsForValue().set(uuidToken, userModel);
        redisTemplate.expire(uuidToken, 1, TimeUnit.HOURS);
        //        this.httpServletRequest.getSession().setAttribute("IS_LOGIN", true);
        //        this.httpServletRequest.getSession().setAttribute("LOGIN_USER", userModel);
        return CommonReturnType.create(uuidToken);
    }

    @RequestMapping(value = "/register", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType register(@RequestParam(name = "telephone") String telephone,
                                     @RequestParam(name = "otpCode") String otpCode,
                                     @RequestParam(name = "name") String name,
                                     @RequestParam(name = "gender") Integer gender,
                                     @RequestParam(name = "age") Integer age,
                                     @RequestParam(name = "password") String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        // 验证手机号和对应的otpCOde相符合
        // String inSessionOtpCode = (String) this.httpServletRequest.getSession().getAttribute(telephone);

        String redisOptCode = (String) redisTemplate.opsForValue().get(telephone);
        if (!StringUtils.equals(redisOptCode, otpCode)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "短信验证码不符合");
        }
        UserModel userModel = new UserModel();
        userModel.setName(name);
        userModel.setGender((byte) gender.intValue());
        userModel.setAge(age);
        userModel.setTelephone(telephone);
        userModel.setRegisterMode("by_phone");

        String encrpPassword = this.encodeByMd5(password);
        userModel.setEncrptPassword(encrpPassword);

        userService.register(userModel);

        return new CommonReturnType().create(null);
    }

    // 用户获取otp短信接口
    @RequestMapping(value = "/getotp", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType getOtp(@RequestParam(name = "telephone") String telephone) {
        // 按照一定的规则生成OTP的验证码
        Random random = new Random();
        int randomInt = random.nextInt(9999);// 范围 [0000, 9999)
        randomInt += 10000;
        String otpCode = String.valueOf(randomInt);
        // this.httpServletRequest.getSession().setAttribute(telephone, otpCode);
        redisTemplate.opsForValue().set(telephone, otpCode);
        redisTemplate.expire(telephone, 1, TimeUnit.MINUTES); // 设置手机验证码的国企时间为1min

        System.out.println("telephone: " + telephone + " otp code: " + otpCode);
        return CommonReturnType.create(null);

    }


    @RequestMapping("/get")
    @ResponseBody
    public CommonReturnType getUser(@RequestParam(name = "id") int id) throws BusinessException {
        // 调用service层的服务对应的id用户对象并返回给前端

        UserModel userModel = this.userService.getUserById(id);

        // 若获取的用户信息不存在，则进行相关的异常处理
        if (null == userModel)
            throw new BusinessException(EmBusinessError.USER_NOT_EXIST);

        UserVO userVO = this.convertFromModel(userModel);

        // 将核心领域模型用户对象转化为可供UI使用的ViewObject
        // 返回前端通用的数据返回对象，包含了状态的信息
        return CommonReturnType.create(userVO);
    }

    private UserVO convertFromModel(UserModel userModel) {
        if (null == userModel)
            return null;

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userModel, userVO);
        return userVO;
    }

}
